package com.code.impl.base;

import com.code.BaseCodeItem;
import com.code.CodeWriter;
import com.code.helper.ProjectHelper;
import com.common.config.ProjectConfig;
import com.common.entity.CClass;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

public class BaseCodeWrite extends CodeWriter {
    private URL resource;

    public BaseCodeWrite(ProjectConfig projectConfig) {
        super(projectConfig);
    }

    @Override
    public void write(CClass cClass) {
        super.write(cClass);
        start();
    }

    @Override
    public void write() {
        super.write();
        start();
    }

    private void start() {
        resource = this.getClass().getResource("/code");
        Optional.ofNullable(resource).map(URL::getPath).map(File::new).filter(File::isDirectory).map(File::listFiles).ifPresent(this::build);
    }

    private void build(File[] files) {
        Arrays.stream(files).map(File::listFiles).filter(Objects::nonNull).forEach(this::forEach);
    }

    private void forEach(File[] files) {
        Arrays.stream(files).filter(File::isDirectory).map(File::listFiles).filter(Objects::nonNull).forEach(this::forEach);
        Arrays.stream(files).filter(File::isFile).map(this::buildStringFromFile).filter(Objects::nonNull).collect(Collectors.toList()).forEach(this::writeToCode);
    }

    private void writeToCode(BaseCodeItem codeItem) {
        String lastPath = codeItem.getLastPath();
        codeItem.write(getBaseCodePath(lastPath));
    }


    private BaseCodeItem buildStringFromFile(File file) {
        try {
            String content = FileUtils.readFileToString(file, StandardCharsets.UTF_8);
            return BaseCodeItem.builder().content(content).lastPath(getPath(file)).fileName(file.getName()).packageName("package  " + getBaseCodePackageName(file) + ";").build();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;

    }

    private String getBaseCodePackageName(File file) {
        return ProjectHelper.getBaseCodePackage(getProjectConfig(), getPath(file));
    }

    private String getPath(File file) {
        String parent = file.getParent();
        int start = resource.getPath().length() + 1;
        int end = parent.length();
        return parent.substring(start, end);
    }


    private String getBaseCodePath(String path) {
        return ProjectHelper.getBaseCodePath(getProjectConfig(), path);
    }
}
